home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / Clocks / Julian / Source / Julian.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  7.2 KB  |  404 lines

  1. #import "Julian.h"
  2. #import <math.h>
  3. #import <stdlib.h>
  4. #import <sys/time.h>
  5. #import <stdio.h>
  6. @implementation Julian
  7.  
  8.  
  9. +  (double) getCurrentDate
  10. {
  11.     int mon,mday,year,hr,min,sec,dow;
  12.     long theDate;
  13.     double theDDate;
  14.     
  15.     struct timeval tp;
  16.     struct timezone tz;
  17.     struct tm *theTime;
  18.     gettimeofday(&tp, &tz);
  19.     theTime = localtime(&(tp.tv_sec));
  20.     
  21.     theDDate = [Julian julianDay:theTime->tm_mday
  22.                                             :theTime->tm_mon+1
  23.                                             :theTime->tm_year+1900
  24.                                             :theTime->tm_hour
  25.                                             :theTime->tm_min
  26.                                             :theTime->tm_sec];
  27.             
  28.     theDate = [Julian julianDay:theTime->tm_mday
  29.                                             :theTime->tm_mon+1
  30.                                             :theTime->tm_year+1900];
  31.             
  32.     #ifdef DEBUG    
  33.         printf("the date is %f\n",theDDate);
  34.     #endif
  35.     
  36.     [Julian calendarDay:theDDate:&mday:&mon:&year:&hr:&min:&sec];
  37.     
  38.     dow = [Julian dow:theDate];
  39.     
  40.     #ifdef DEBUG
  41.         printf(" mm/dd/yy hh:mm:ss  = %02i/%02i/%04i  %02i:%02i:%02i and dow = %i\n"
  42.         ,mon,mday,year,hr,min,sec,dow);
  43.     #endif
  44.     
  45.     return theDDate;
  46. }
  47.  
  48.  
  49.  
  50. // Given a day month and year, calculate the julian date.
  51. + (double) julianDay:(int) day :(int) month :(int) year
  52. {
  53. int a,b;
  54. double retVal;
  55.  
  56. float yearCorr;
  57.  
  58.     //Correct for negitive year
  59.     yearCorr = (year > 0? 0.0 : 0.75);
  60.     if( month <= 2)
  61.     {
  62.         year--;
  63.         month += 12;
  64.     }
  65.     b = 0;
  66.     //Deal with Gregorian reform
  67.     if( (year * 10000.0) + (month * 100.0) + day >= 15821015.0)
  68.     {
  69.         a = year / 100;
  70.         b = (2-a)+(a/4);
  71.     }
  72.     
  73.     retVal = (long) ( (365.25 * year) - yearCorr);
  74.     retVal += (long) (30.6001 * (month+1));
  75.     retVal += (long) day;
  76.     retVal += 1720994L;
  77.     retVal += (long) b;
  78.     return(retVal);
  79. }
  80.  
  81. + (double)    julianDay    :(int) day
  82.                                  :(int) month
  83.                                 :(int) year
  84.                                 :(int) hour
  85.                                 :(int) min
  86.                                 :(int) sec
  87. {
  88. double retVal;
  89. double retFraction;
  90.  
  91.  
  92.     retVal = [self julianDay:day:month:year];
  93.     
  94.     retFraction =         (double)((double)hour/24.0)
  95.                          + (double)((double)min/1440.0)
  96.                          + (double)((double)sec/86400.0);
  97.                                                   
  98.     return  (retVal+retFraction);
  99. }
  100.  
  101.  
  102. //Given a julian date, calculate the month day and year.
  103. //The year will be Negitive if it's BC
  104. + (void)     calendarDay    :(double)julian
  105.                                 :(int *)    day
  106.                                 :(int *)    month
  107.                                 :(int *) year
  108. {
  109. long a,b,c,d,e,z, alpha;
  110.     
  111.     z = julian + 1;
  112.     //Deal with Gregorian reform
  113.     if( z < 2299161L)
  114.         a = z;
  115.     else
  116.     {
  117.         alpha = (long) (( z - 1867216.25) / 36524.25);
  118.         a = z + 1 + alpha - alpha / 4;
  119.     }
  120.     b = a + 1524;
  121.     c = (long) (( b - 122.1) / 365.25);
  122.     d = (long) (365.25 * c);
  123.     e = (long) (( b - d ) / 30.6001);
  124.     *day         = (int) b - d - (long) (30.6001 * e);
  125.     *month     = (int) ( e < 13.5) ? e - 1 : e - 13;
  126.     *year     = (int) (*month > 2.5) ? (c - 4716) : c - 4715;
  127. }
  128.  
  129. + (void)     calendarDay    :(double)    julian
  130.                                 :(int *)    day
  131.                                 :(int *)    month
  132.                                 :(int *) year
  133.                                 :(int *)    hour
  134.                                 :(int *)    min
  135.                                 :(int *) sec
  136. {
  137. double fractionalPart;
  138. double tmpResult;
  139. double integerPart;
  140.  
  141.     [self calendarDay    :(long) julian
  142.                             : day
  143.                             : month
  144.                             : year];
  145.     //days.fractionalDays
  146.     fractionalPart = modf((double)julian,&integerPart);
  147.         
  148.     tmpResult = fractionalPart * 24.0;
  149.     fractionalPart = modf(tmpResult,&integerPart);
  150.     *hour = (int) integerPart;
  151.     
  152.     tmpResult  = fractionalPart *  60.0;
  153.     fractionalPart = modf(tmpResult,&integerPart);
  154.     *min = (int) integerPart;
  155.     
  156.     tmpResult  = fractionalPart *  60.0;
  157.     fractionalPart = modf(tmpResult,&integerPart);
  158.     *sec = (int) integerPart;
  159.         
  160. }
  161.  
  162. //See if the passed in date is a Valid date
  163. // I.E. Feb 29 on a non leap year is NOT valid
  164. // returns YES if date is OK
  165. + (BOOL)     validDay        :(int)    day
  166.                                 :(int)    month
  167.                                 :(int)    year
  168. {
  169. int calDay;
  170. int calMonth;
  171. int calYear;
  172.  
  173.     //convert it to julian
  174.     [self calendarDay:[self julianDay:day:month:year]
  175.                             : &calDay
  176.                             : &calMonth
  177.                             : &calYear];
  178.     
  179.     return(( day == calDay) && (month == calMonth) && (year == calYear) );
  180.     
  181. }
  182.  
  183.  
  184.  
  185. + (BOOL)     validDay        :(int)    day
  186.                                 :(int)    month
  187.                                 :(int)    year
  188.                                 :(int)    hour
  189.                                 :(int)    min
  190.                                 :(int)    sec
  191. {
  192. int calDay;
  193. int calMonth;
  194. int calYear;
  195. int calHour;
  196. int calMin;
  197. int calSec;
  198.  
  199.     //convert it to julian
  200.     [self calendarDay:[self julianDay:day:month:year:hour:min:sec]
  201.                             : &calDay
  202.                             : &calMonth
  203.                             : &calYear
  204.                             : &calHour
  205.                             : &calMin
  206.                             : &calSec];
  207.     return(     (day == calDay)
  208.             && (month == calMonth)
  209.             && (year == calYear)
  210.             && (hour == calHour)
  211.             && (min == calMin)
  212.             && (sec == calSec)
  213.             );
  214. }
  215.  
  216. //0=Sunday 2 = Monday .... 6 = Saturday
  217. + (int)        dow:(long) julian
  218. {
  219.     return (int) ((( julian + 2) % 7) + 1);
  220. }
  221.  
  222. //week days from past dates
  223. + (double)     wkd:(int)    day
  224.                 :(int)    month
  225.                 :(int)    year
  226. {
  227. long d;
  228. double g;
  229. double f;
  230. double ans;
  231.  
  232.  
  233.     g = (month > 2) ? year : year-1;
  234.     f = (month > 2) ? month + 1 : month + 13;
  235.     
  236.     
  237.     d = day - (int) ( 0.75* (int) (g/100.0)-7) +
  238.                     (int) (365.25*g) + (int) (30.6*f);
  239.     
  240.     d-=2;                
  241.     ans = (5* (int) (d/7)) + (0.5*(int) (1.801* (d % 7)));
  242.     return ans;
  243. }
  244.  
  245.  
  246.  
  247.  
  248. //  Day of year
  249. + (int)     doy:(int)    day
  250.                 :(int)    month
  251.                 :(int)    year
  252. {
  253. double curJulianDay;
  254. double janJulianDay;
  255.  
  256.     curJulianDay =[Julian  julianDay:(int) day
  257.                                             :(int) month
  258.                                             :(int) year];
  259.                                             
  260.     janJulianDay = [Julian  julianDay:(int) 1
  261.                                             :(int) 1
  262.                                             :(int) year];
  263.                                     
  264.     return (int) ( (curJulianDay - janJulianDay) + 1.0);
  265. }
  266.  
  267.  
  268.  
  269. //instance methods
  270.  
  271. - init;
  272. {
  273.     julianDayVal = 0.0;
  274.     return self;
  275. }
  276. - (BOOL) initDay    
  277.                 :(int) month    
  278.                 :(int) day
  279.                 :(int) year
  280. {
  281.     [super init];
  282.     return [self setJulianDay:month:day:year];
  283. }
  284.                 
  285. - (BOOL) initDay    
  286.                 :(int) month    
  287.                 :(int) day
  288.                 :(int) year
  289.                 :(int) hour
  290.                 :(int) min
  291.                 :(int) sec
  292. {
  293.     [super init];
  294.     return [ self  setJulianDay
  295.                                 :month
  296.                                 :day
  297.                                 :year
  298.                                 :hour
  299.                                 :min
  300.                                 :sec];
  301. }
  302.  
  303. - read:(NXTypedStream *)stream
  304. {
  305.     [super read:stream];
  306.     /* class-specific code goes here */
  307.           NXReadType(stream,"d",&julianDayVal);
  308.  
  309.     return self;
  310. }
  311.  
  312. - write:(NXTypedStream *)stream
  313. {
  314.     [super write:stream];
  315.     /* class-specific archiving code goes here */
  316.      NXWriteType(stream,"d",&julianDayVal);
  317.     return self;
  318. }
  319.  
  320. - (double)     getJulianDay
  321. {
  322.     return julianDayVal;
  323. }
  324.  
  325. -  getCalandarDay            :(int*) month
  326.                                  :(int*) day
  327.                                 :(int*) year
  328. {
  329.     [Julian calendarDay    : julianDayVal
  330.                                 : day
  331.                                 : month
  332.                                 : year];
  333.     return self;
  334. }
  335.  
  336.                                 
  337. -  getCalandarDay            :(int*) month
  338.                                  :(int*) day
  339.                                 :(int*) year
  340.                                  :(int*) hour
  341.                                  :(int*) min
  342.                                  :(int*) sec
  343. {
  344.     [Julian calendarDay    : julianDayVal
  345.                                 : day
  346.                                 : month
  347.                                 : year
  348.                                 : hour
  349.                                 : min
  350.                                 : sec];
  351.     
  352.     return self;
  353. }
  354.  
  355. - (BOOL) setJulianDay    :(double) day
  356. {
  357.     julianDayVal = day;
  358.     return YES;
  359. }
  360.  
  361.  
  362. - (BOOL)    setJulianDay    :(int) month
  363.                                 :(int) day
  364.                                 :(int) year
  365. {
  366.     if( [Julian validDay    :(int) month
  367.                                 :(int) day
  368.                                 :(int) year])
  369.         {
  370.             julianDayVal = [Julian  julianDay:(int) month
  371.                                                         :(int) day
  372.                                                         :(int) year];
  373.             return YES;
  374.         }
  375.     return NO;
  376. }    
  377.                     
  378. - (BOOL) setJulianDay    :(int) month
  379.                                 :(int) day
  380.                                 :(int) year
  381.                                 :(int) hour
  382.                                 :(int) min
  383.                                 :(int) sec
  384. {
  385.     if( [Julian validDay    :(int) month
  386.                                 :(int) day
  387.                                 :(int) year
  388.                                 :(int) hour
  389.                                 :(int) min
  390.                                 :(int) sec])
  391.     {
  392.          julianDayVal = [Julian validDay    
  393.                                 :(int) month
  394.                                 :(int) day
  395.                                 :(int) year
  396.                                 :(int) hour
  397.                                 :(int) min
  398.                                 :(int) sec];
  399.         return YES;
  400.     }
  401.     return NO;
  402. }
  403. @end
  404.